library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity link_tb is
end link_tb; 

architecture tb of link_tb is
  
  component link is

    port ( clk            : in  std_ulogic;
           initialize     : in  std_ulogic;
           reset_in       : in  std_ulogic;
           link_data_in   : in  std_ulogic;
           h_target_label : in  std_logic_vector(31 DownTo 0);
           reset_out      : out std_ulogic;
           link_data_out  : out std_ulogic;
           link_killed    : out std_ulogic
         );
    
  end component;

  -- Global Signals
  signal clk            : std_ulogic;
  signal link_a_to_b    : std_ulogic;

  -- link a specific signals
  signal init_a         : std_ulogic;
  signal reset_a        : std_ulogic;
  signal reset_out_a    : std_ulogic;
  signal target_label_a : std_logic_vector(31 DownTo 0);
  signal data_out_a     : std_ulogic;
  signal link_killed_a  : std_ulogic;

  -- link b specific signals
  signal init_b         : std_ulogic;
  signal reset_b        : std_ulogic;
  signal reset_out_b    : std_ulogic;
  signal target_label_b : std_logic_vector(31 DownTo 0);
  signal data_out_b     : std_ulogic;
  signal link_killed_b  : std_ulogic;
         
begin

  a_link : link port map ( clk, 
                           init_a, 
                           reset_a,
                           link_a_to_b,
                           target_label_a,
                           reset_out_a,
                           data_out_a,
                           link_killed_a
                         );

  b_link : link port map ( clk, 
                           init_b, 
                           reset_b,
                           link_a_to_b,
                           target_label_b,
                           reset_out_b,
                           data_out_b,
                           link_killed_b
                         );

  process

    variable out_loop : integer;
    variable in_loop : integer;

    procedure clock_link is
    begin
      clk <= '1';
      wait for 1 ns;
      clk <= '0';
      wait for 1 ns;
    end clock_link;

  begin

    init_a <= '1';
    init_b <= '1';
    wait for 1 ns;

    target_label_a <= "01001000100010001000100010001000";
    target_label_b <= "00001000100010001000100010001000";
    wait for 1 ns;

    reset_a <= '0';
    reset_b <= '0';
    wait for 1 ns;

    for out_loop in 1 to 32 loop

      clock_link;
      clock_link;

      -- link reset is read on this cycle

      clock_link;
      clock_link;
      clock_link;
      
      -- link data set on this clock cycle

      clock_link;
      clock_link;
      clock_link;
      
    end loop;

    wait;

  end process;


  data_link_set : process ( data_out_a, data_out_b )
  begin
      
    -- filter unitialized values
    if ( data_out_a = 'U' or data_out_b = 'U' ) then

    else 

      -- write link data if values exist
      link_a_to_b <= data_out_a or data_out_b;

    end if;

  end process data_link_set;

end tb;

